package com.mvvm.start.base.utils

import android.app.Dialog
import android.content.Context
import androidx.activity.ComponentActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import java.lang.reflect.ParameterizedType

/**
 * @功能:
 * @User Lmy
 * @Creat 2021/10/27 2:22 下午
 * @Compony 永远相信美好的事情即将发生
 */
object ViewModelUtils {


    /**
     * Activity中使用 通过反射初始化ViewModle可以选择传入factory参数
     * @param activity ComponentActivity 上下文
     * @param factory Factory? 传递进ViewModle中的参数
     * @param position Int 反射获取指定的类型参数
     * @return VM
     */
    fun <VM : ViewModel> createViewModel(
        activity: ComponentActivity,
        factory: ViewModelProvider.Factory? = null,
        position: Int
    ): VM {
        val vbClass =
            (activity.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments.filterIsInstance<Class<*>>()
        val viewModel = vbClass[position] as Class<VM>
        return factory?.let {
            ViewModelProvider(
                activity,
                factory
            ).get(viewModel)
        } ?: let {
            ViewModelProvider(activity).get(viewModel)
        }
    }

    /**
     * Fragment中使用通过反射初始化ViewModle可以选择传入factory参数
     * @param fragment Fragment 上下文
     * @param factory Factory? 传递进ViewModle中的参数
     * @param position Int 反射获取指定的类型参数
     * @return VM
     */
    fun <VM : ViewModel> createViewModel(
        fragment: Fragment,
        factory: ViewModelProvider.Factory? = null,
        position: Int
    ): VM {
        val vbClass =
            (fragment.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments.filterIsInstance<Class<*>>()
        val viewModel = vbClass[position] as Class<VM>
        return factory?.let {
            ViewModelProvider(
                fragment,
                factory
            ).get(viewModel)
        } ?: let {
            ViewModelProvider(fragment).get(viewModel)
        }
    }

    /**
     * Fragment中使用通过反射初始化ViewModle可以选择传入factory参数
     * 共享Activity中的ViewModle
     * @param fragment Fragment 上下文
     * @param factory Factory? 传递进ViewModle中的参数
     * @param position Int 反射获取指定的类型参数
     * @return VM
     */
    fun <VM : ViewModel> createActivityViewModel(
        fragment: Fragment,
        factory: ViewModelProvider.Factory? = null,
        position: Int
    ): VM {
        val vbClass =
            (fragment.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments.filterIsInstance<Class<*>>()
        val viewModel = vbClass[position] as Class<VM>
        return factory?.let {
            ViewModelProvider(
                fragment.requireActivity(),
                factory
            ).get(viewModel)
        } ?: let {
            ViewModelProvider(fragment.requireActivity()).get(viewModel)
        }
    }



}
